import { defineStore } from 'pinia'
import { getDicts, getDictsByTypeTree } from '@/api/system/dict'
import type { IGetDictsRes, IDictItem } from '@/api/system/dict/type'
import { getOrgDictApi } from '@/api/athlete'
import { isStaticDict, getStaticDict, ORG_DICT } from '@/constants'

interface DictCache {
	expireTime: number // 过期时间戳
	data: IGetDictsRes // 字典数据
}

// 组织级联项
export interface OrgCascadeItem {
	label: string
	value: number // 修正为 number 类型
	children?: Array<{ label: string; value: number }> // 修正为 number 类型
}

// 组织字典项（注册单位、在训单位）
export interface OrgDictItem {
	label: string
	value: number // number 类型
}

interface OrgCascadeCache {
	expireTime: number
	data: OrgCascadeItem[]
}

// 组织字典缓存（注册单位、在训单位）
interface OrgDictCache {
	expireTime: number
	data: OrgDictItem[]
}

// 运动员在训单位：类型、级别级联
interface TrainOrgTypeLevelCascadeCache {
	expireTime: number
	data: IDictItem[]
}

interface DictState {
	// 存储所有字典数据 key: dictType, value: 缓存对象
	dicts: Record<string, DictCache>
	// 组织级联数据缓存（注册单位/在训单位复用）
	orgCascade: OrgCascadeCache | null
	// 注册单位字典缓存（所有二级节点的扩平列表）
	registerOrgs: OrgDictCache | null
	// 在训单位字典缓存（所有二级节点的扩平列表）
	trainOrgs: OrgDictCache | null
	// 运动员在训单位：类型、级别级联
	trainOrgTypeLevelCascade: TrainOrgTypeLevelCascadeCache | null
	// 正在加载的字典集合（避免重复请求）
	loadingDicts: Set<string>
	// 组织级联是否正在加载
	loadingOrgCascade: boolean
	// 注册单位字典是否正在加载
	loadingRegisterOrgs: boolean
	// 在训单位字典是否正在加载
	loadingTrainOrgs: boolean
	// 运动员在训单位：类型、级别级联是否正在加载
	loadingTrainOrgTypeLevelCascade: boolean
}

// 默认缓存时间：30分钟
const DEFAULT_CACHE_TIME = 30 * 60 * 1000
// 组织级联默认缓存：30分钟
const DEFAULT_ORG_CACHE_TIME = 30 * 60 * 1000

export const useDictStore = defineStore('dict', {
	state: (): DictState => ({
		dicts: {},
		orgCascade: null,
		registerOrgs: null,
		trainOrgs: null,
		trainOrgTypeLevelCascade: null,
		loadingDicts: new Set(),
		loadingOrgCascade: false,
		loadingRegisterOrgs: false,
		loadingTrainOrgs: false,
		loadingTrainOrgTypeLevelCascade: false
	}),

	getters: {
		// 获取指定字典（响应式数据，自动加载）
		getDict(state) {
			const store = this as any // 解决 TypeScript 类型推断问题
			return (dictType: string) => {
				// 优先检查是否为静态字典
				if (isStaticDict(dictType)) {
					return getStaticDict(dictType) || []
				}

				// 检查缓存是否过期
				const cache = state.dicts[dictType]
				const isExpired = !cache || Date.now() > cache.expireTime

				// 如果缓存过期且未在加载中，自动触发加载
				if (isExpired && !state.loadingDicts.has(dictType)) {
					store.loadDict(dictType)
				}

				// 返回当前数据（可能为空或旧数据）
				return cache?.data || []
			}
		},

		// 检查字典缓存是否过期
		isExpired: state => (dictType: string) => {
			const cache = state.dicts[dictType]
			if (!cache) return true
			return Date.now() > cache.expireTime
		},

		// 获取组织级联数据（自动加载）
		getOrgCascade(state) {
			const store = this as any // 解决 TypeScript 类型推断问题
			// 检查缓存是否过期
			const isExpired = !state.orgCascade || Date.now() > state.orgCascade.expireTime

			// 如果缓存过期且未在加载中，自动触发加载
			if (isExpired && !state.loadingOrgCascade) {
				store.loadOrgCascade()
			}

			// 返回当前数据（可能为空或旧数据）
			return state.orgCascade?.data || []
		},

		// 组织级联数据是否过期
		isOrgCascadeExpired: state => {
			if (!state.orgCascade) return true
			return Date.now() > state.orgCascade.expireTime
		},

		// 获取注册单位字典（自动加载）
		getRegisterOrgs(state) {
			const store = this as any
			// 检查缓存是否过期
			const isExpired = !state.registerOrgs || Date.now() > state.registerOrgs.expireTime

			// 如果缓存过期且未在加载中，自动触发加载
			if (isExpired && !state.loadingRegisterOrgs) {
				store.loadRegisterOrgs()
			}

			// 返回当前数据（可能为空或旧数据）
			return state.registerOrgs?.data || []
		},

		// 注册单位字典是否过期
		isRegisterOrgsExpired: state => {
			if (!state.registerOrgs) return true
			return Date.now() > state.registerOrgs.expireTime
		},

		// 获取在训单位字典（自动加载）
		getTrainOrgs(state) {
			const store = this as any
			// 检查缓存是否过期
			const isExpired = !state.trainOrgs || Date.now() > state.trainOrgs.expireTime

			// 如果缓存过期且未在加载中，自动触发加载
			if (isExpired && !state.loadingTrainOrgs) {
				store.loadTrainOrgs()
			}

			// 返回当前数据（可能为空或旧数据）
			return state.trainOrgs?.data || []
		},

		// 在训单位字典是否过期
		isTrainOrgsExpired: state => {
			if (!state.trainOrgs) return true
			return Date.now() > state.trainOrgs.expireTime
		},

		// 获取运动员在训单位：类型、级别级联（自动加载）
		getTrainOrgTypeLevelCascade(state) {
			const store = this as any
			// 检查缓存是否过期
			const isExpired = !state.trainOrgTypeLevelCascade || Date.now() > state.trainOrgTypeLevelCascade.expireTime

			// 如果缓存过期且未在加载中，自动触发加载
			if (isExpired && !state.loadingTrainOrgTypeLevelCascade) {
				store.loadTrainOrgTypeLevelCascade()
			}

			// 返回当前数据（可能为空或旧数据）
			return state.trainOrgTypeLevelCascade?.data || []
		},

		// 运动员在训单位：类型、级别级联是否过期
		isTrainOrgTypeLevelCascadeExpired: state => {
			if (!state.trainOrgTypeLevelCascade) return true
			return Date.now() > state.trainOrgTypeLevelCascade.expireTime
		}
	},

	actions: {
		// 加载字典数据
		async loadDict(dictType: string, cacheTime: number = DEFAULT_CACHE_TIME) {
			// 静态字典直接返回，无需加载
			if (isStaticDict(dictType)) {
				return getStaticDict(dictType) || []
			}

			// 如果缓存未过期，直接返回缓存数据
			if (!this.isExpired(dictType)) {
				return this.dicts[dictType].data
			}

			// 如果正在加载中，返回当前数据（避免重复请求）
			if (this.loadingDicts.has(dictType)) {
				return this.dicts[dictType]?.data || []
			}

			// 标记为加载中
			this.loadingDicts.add(dictType)

			// 初始化字典（如果不存在）
			if (!this.dicts[dictType]) {
				this.dicts[dictType] = {
					expireTime: 0,
					data: []
				}
			}

			try {
				const data = await getDicts(dictType)
				// 更新缓存数据和过期时间
				this.dicts[dictType].data = data
				this.dicts[dictType].expireTime = Date.now() + cacheTime
				return data
			} catch (error) {
				console.error(`加载字典失败: ${dictType}`, error)
				// 失败时保持空数组，但设置短暂过期时间（30秒后重试）
				if (!this.dicts[dictType]) {
					this.dicts[dictType] = {
						expireTime: Date.now() + 30000,
						data: []
					}
				} else {
					this.dicts[dictType].data = []
					this.dicts[dictType].expireTime = Date.now() + 30000
				}
				return []
			} finally {
				// 移除加载标记
				this.loadingDicts.delete(dictType)
			}
		},

		// 批量加载多个字典
		async loadDicts(dictTypes: string[]) {
			// 预加载组织相关数据
			await Promise.all([
				this.loadOrgCascade(), // 加载在训单位级联数据
				this.loadRegisterOrgs(), // 加载注册单位数据
				this.loadTrainOrgs(), // 加载在训单位数据
				this.loadTrainOrgTypeLevelCascade() // 加载运动员在训单位：类型、级别级联
			])
			// 并发加载所有字典
			const promises = dictTypes.map(type => this.loadDict(type))
			await Promise.all(promises)
		},

		// 加载组织级联数据
		async loadOrgCascade(cacheTime: number = DEFAULT_ORG_CACHE_TIME) {
			// 缓存有效则直接返回
			if (!this.isOrgCascadeExpired) {
				return this.orgCascade!.data
			}

			// 如果正在加载中，返回当前数据（避免重复请求）
			if (this.loadingOrgCascade) {
				return this.orgCascade?.data || []
			}

			// 标记为加载中
			this.loadingOrgCascade = true

			try {
				// 先加载一级数据（单位类型）
				const firstLevel = await this.loadDict('comp_athlete_second_org_type')

				// 并发加载二级
				const results = await Promise.all(
					firstLevel.map(async (item: any) => {
						const res = await getOrgDictApi(2, Number(item.value))
						// 在训单位类型
						const children = Object.entries(res.data || {}).map(([key, value]) => ({
							label: String(value),
							value: Number(key)
						}))
						return {
							label: item.label as string,
							value: Number(item.value),
							children
						} as OrgCascadeItem
					})
				)

				console.log('loadOrgCascade:', results)

				this.orgCascade = {
					data: results,
					expireTime: Date.now() + cacheTime
				}
				return results
			} catch (error) {
				console.error('加载组织级联数据失败:', error)
				this.orgCascade = {
					data: [],
					expireTime: Date.now() + 30000
				}
				return []
			} finally {
				// 移除加载标记
				this.loadingOrgCascade = false
			}
		},

		// 加载运动员在训单位：类型、级别级联
		async loadTrainOrgTypeLevelCascade(cacheTime: number = DEFAULT_ORG_CACHE_TIME) {
			// 缓存有效则直接返回
			if (!this.isTrainOrgTypeLevelCascadeExpired) {
				return this.trainOrgTypeLevelCascade!.data
			}

			// 如果正在加载中，返回当前数据（避免重复请求）
			if (this.loadingTrainOrgTypeLevelCascade) {
				return this.trainOrgTypeLevelCascade?.data || []
			}

			// 标记为加载中
			this.loadingTrainOrgTypeLevelCascade = true

			try {
				// 使用级联字典接口获取 运动员在训单位：类型、级别级联
				const data = await getDictsByTypeTree(ORG_DICT.TRAIN_TYPE)

				console.log('loadTrainOrgTypeLevelCascade:', data)

				this.trainOrgTypeLevelCascade = {
					data,
					expireTime: Date.now() + cacheTime
				}
				return data
			} catch (error) {
				console.error('加载运动员在训单位：类型、级别级联失败:', error)
				this.trainOrgTypeLevelCascade = {
					data: [],
					expireTime: Date.now() + 30000
				}
				return []
			} finally {
				// 移除加载标记
				this.loadingTrainOrgTypeLevelCascade = false
			}
		},

		// 强制刷新字典（忽略缓存）
		async refreshDict(dictType: string) {
			delete this.dicts[dictType]
			return await this.loadDict(dictType)
		},

		// 强制刷新组织级联
		async refreshOrgCascade() {
			this.orgCascade = null
			return await this.loadOrgCascade()
		},

		// 强制刷新运动员在训单位：类型、级别级联
		async refreshTrainOrgTypeLevelCascade() {
			this.trainOrgTypeLevelCascade = null
			return await this.loadTrainOrgTypeLevelCascade()
		},

		// 加载注册单位字典（所有二级节点的扁平列表）
		async loadRegisterOrgs(cacheTime: number = DEFAULT_ORG_CACHE_TIME) {
			// 缓存有效则直接返回
			if (!this.isRegisterOrgsExpired) {
				return this.registerOrgs!.data
			}

			// 如果正在加载中，返回当前数据（避免重复请求）
			if (this.loadingRegisterOrgs) {
				return this.registerOrgs?.data || []
			}

			// 标记为加载中
			this.loadingRegisterOrgs = true

			try {
				// 调用 API 获取所有注册单位
				const res = await getOrgDictApi(1)

				// 转换为字典格式，value 为 number 类型
				const data = Object.entries(res.data || {}).map(([key, value]) => ({
					label: String(value),
					value: Number(key) // 保存为 number 类型
				}))

				this.registerOrgs = {
					data,
					expireTime: Date.now() + cacheTime
				}

				return data
			} catch (error) {
				console.error('加载注册单位字典失败:', error)
				this.registerOrgs = {
					data: [],
					expireTime: Date.now() + 30000
				}
				return []
			} finally {
				// 移除加载标记
				this.loadingRegisterOrgs = false
			}
		},

		// 加载在训单位字典（所有二级节点的扁平列表）
		async loadTrainOrgs(cacheTime: number = DEFAULT_ORG_CACHE_TIME) {
			// 缓存有效则直接返回
			if (!this.isTrainOrgsExpired) {
				return this.trainOrgs!.data
			}

			// 如果正在加载中，返回当前数据（避免重复请求）
			if (this.loadingTrainOrgs) {
				return this.trainOrgs?.data || []
			}

			// 标记为加载中
			this.loadingTrainOrgs = true

			try {
				// 调用 API 获取所有在训单位
				const res = await getOrgDictApi(2)

				// 转换为字典格式，value 为 number 类型
				const data = Object.entries(res.data || {}).map(([key, value]) => ({
					label: String(value),
					value: Number(key) // 保存为 number 类型
				}))

				this.trainOrgs = {
					data,
					expireTime: Date.now() + cacheTime
				}

				return data
			} catch (error) {
				console.error('加载在训单位字典失败:', error)
				this.trainOrgs = {
					data: [],
					expireTime: Date.now() + 30000
				}
				return []
			} finally {
				// 移除加载标记
				this.loadingTrainOrgs = false
			}
		},

		// 清除指定字典缓存
		clearDict(dictType: string) {
			delete this.dicts[dictType]
		},

		// 清除组织级联缓存
		clearOrgCascade() {
			this.orgCascade = null
		},

		// 清除运动员在训单位：类型、级别级联缓存
		clearTrainOrgTypeLevelCascade() {
			this.trainOrgTypeLevelCascade = null
		},

		// 清除注册单位字典缓存
		clearRegisterOrgs() {
			this.registerOrgs = null
		},

		// 清除在训单位字典缓存
		clearTrainOrgs() {
			this.trainOrgs = null
		},

		// 清除所有字典缓存
		clearAll() {
			this.dicts = {}
			this.orgCascade = null
			this.registerOrgs = null
			this.trainOrgs = null
			this.trainOrgTypeLevelCascade = null
		},

		// 强制刷新注册单位字典
		async refreshRegisterOrgs() {
			this.registerOrgs = null
			return await this.loadRegisterOrgs()
		},

		// 强制刷新在训单位字典
		async refreshTrainOrgs() {
			this.trainOrgs = null
			return await this.loadTrainOrgs()
		}
	}
})
